﻿using System;
using System.Collections.Generic;
using System.Linq;
using eCommerce.Core.Data;
using eCommerce.Core.Domain.Products;
using eCommerce.Models.Product;

namespace eCommerce.Services.Products
{
    public class ProductService:IProductService
    {
        private IRepository<ItemGroup> _itemGroupRep;
        private IRepository<Item> _itemRep;
        private IRepository<Product> _productRep;
        private IRepository<ProductAttributeKey> _productAttributeKeyRep;
        private IRepository<ProductAttributeValue> _productAttributeValueRep;

        private IRepository<ItemAttributeKey> _itemAttributeKeyRep;
        private IRepository<ItemAttributeValue> _itemAttributeValueRep;

        public ProductService(IRepository<Product> productRep, 
            IRepository<ProductAttributeKey> productAttributeKeyRep, 
            IRepository<Item> itemRep, 
            IRepository<ProductAttributeValue> productAttributeValueRep, IRepository<ItemAttributeKey> itemAttributeKeyRep, IRepository<ItemAttributeValue> itemAttributeValueRep, IRepository<ItemGroup> itemGroupRep)
        {
            _productRep = productRep;
            _productAttributeKeyRep = productAttributeKeyRep;
            _itemRep = itemRep;
            _productAttributeValueRep = productAttributeValueRep;
            _itemAttributeKeyRep = itemAttributeKeyRep;
            _itemAttributeValueRep = itemAttributeValueRep;
            _itemGroupRep = itemGroupRep;
        }

        //private IRepository<ProductVariant> _productVariantRepository;
        //private IRepository<ProductAttribute> _productAttributeRepository;
        //private IRepository<ProductVariantAttribute> _productVariantAttributeRepository;
        //private IRepository<ProductVariantAttributeValue> _productVariantAttributeValueRepository;
        //private IRepository<SpecificationAttribute> _spRepository;
        //private IRepository<SpecificationAttributeOption> _spOptionRepository;
        //private IRepository<Picture> _picRepository;
        //private IRepository<ProductPicture> _productPictureRepository;

        //public ProductService(IRepository<Product> productRepository, IRepository<ProductVariant> productVariantRepository, IRepository<ProductAttribute> productAttributeRepository, IRepository<SpecificationAttribute> spRepository, IRepository<Picture> picRepository, IRepository<SpecificationAttributeOption> spOptionRepository, IRepository<ProductVariantAttribute> productVariantAttributeRepository, IRepository<ProductVariantAttributeValue> productVariantAttributeValueRepository, IRepository<ProductPicture> productPictureRepository)
        //{
        //    _productRepository = productRepository;
        //    _productVariantRepository = productVariantRepository;
        //    _productAttributeRepository = productAttributeRepository;
        //    _spRepository = spRepository;
        //    _picRepository = picRepository;
        //    _spOptionRepository = spOptionRepository;
        //    _productVariantAttributeRepository = productVariantAttributeRepository;
        //    _productVariantAttributeValueRepository = productVariantAttributeValueRepository;
        //    _productPictureRepository = productPictureRepository;
        //}

        //public void DeleteProduct(Product product)
        //{
        //    throw new System.NotImplementedException();
        //}

        //public IList<Product> GetAllProducts()
        //{
        //    throw new System.NotImplementedException();
        //}

        //public IList<Product> GetAllProductsByShopPid(int shopId)
        //{

        //    var query = from s in _productRepository.Table
        //                where s.ShopId==shopId 
        //                select s;

        //    var p = query.ToList();
        //    if (p != null)
        //    {

        //        return ProductMapper.ToProducts(p);
        //    }
        //    else
        //    {
        //        return null;
        //    }
        //}

        //public void DeleteProduct(int productId)
        //{
        //    var query = from s in _productRepository.Table
        //                where s.Id == productId
        //                select s;

        //    var p = query.SingleOrDefault();
        //    if (p != null)
        //    {

        //        p.Deleted = true;

        //    }
        //}

        //public Product GetProductById(int productId)
        //{
        //    var query = from s in _productRepository.Table
        //                where s.Id ==productId
        //                select s;

        //    var p = query.SingleOrDefault();
        //    if (p != null)
        //    {

        //        return ProductMapper.ToProduct(p);

                
        //    }
        //    else
        //    {
        //        return null;
        //    }

        //}

     

        //public void InsertProduct(Product product)
        //{
        //    throw new System.NotImplementedException();
        //}

        //public void UpdateProduct(Product product)
        //{
        //    throw new System.NotImplementedException();
        //}

        //public ProductInfoInsertResult InsertProductInfo(ProductInfoInsertRequest productInfoInsertRequest)
        //{
        //    var result = new ProductInfoInsertResult();

        //    try
        //    {
        //        var p = new Product();
        //        p.ShopId = productInfoInsertRequest.ShopId;
        //        p.ProductName = productInfoInsertRequest.ProductName;
        //        p.ShortDescription = productInfoInsertRequest.ShortDescription;
        //        p.FullDescription = productInfoInsertRequest.FullDescription;
        //        p.Published = productInfoInsertRequest.IsPublished;
        //        p.Deleted = false;
        //        p.CreatedOnUtc = DateTime.Now;
        //        p.UpdatedOnUtc = DateTime.Now;

        //        _productRepository.Insert(p);

        //        result.Id = p.Id;

        //        var pv = new ProductVariant();

        //        pv.ProductId = p.Id;

        //        pv.PictureId = productInfoInsertRequest.PictureIds[0];
        //        pv.Published = productInfoInsertRequest.IsPublished;
        //        pv.DisplayOrder = 1;
        //        pv.StockQuantity = productInfoInsertRequest.StockQuantity;
        //        pv.Price = productInfoInsertRequest.Price;
        //        pv.CreatedOnUtc = DateTime.Now;
        //        pv.UpdatedOnUtc = DateTime.Now;
        //        _productVariantRepository.Insert(pv);


        //        foreach (var picId in productInfoInsertRequest.PictureIds)
        //        {
        //            var pp = new ProductPicture()
        //            {
        //                PictureId = picId,
        //                ProductId = p.Id
        //            };
        //            _productPictureRepository.Insert(pp);
        //        }
               
        //    }
        //    catch (Exception e)
        //    {
        //        result.AddError(e.Message);
        //    }
        //    return result;
        //}

        //public ProductInfoUpdateResult UpdateProductInfo(ProductInfoUpdateRequest productInfoUpdateRequest)
        //{
        //    var result = new ProductInfoUpdateResult();

        //    try
        //    {

        //        var p = _productRepository.GetById(productInfoUpdateRequest.Id);
        //        if (p == null)
        //        {
        //            throw new Exception("product not exist");
        //        }

        //        p.ProductName = productInfoUpdateRequest.ProductName;
        //        p.ShortDescription = productInfoUpdateRequest.ShortDescription;
        //        p.FullDescription = productInfoUpdateRequest.FullDescription;
        //        p.Published = productInfoUpdateRequest.IsPublished;

        //        _productRepository.Update(p);
           
        //    }
        //    catch (Exception e)
        //    {
        //        result.AddError(e.Message);
        //    } 
        //    return result;
        //}

        //public ProductVariant GetProductVariantById(int productVariantId)
        //{
        //    var query = from s in _productVariantRepository.Table
        //                where s.Id == productVariantId
        //                select s;

        //    var p = query.SingleOrDefault();
        //    if (p != null)
        //    {

        //        return ProductMapper.ToProductVariant(p);
        //    }
        //    else
        //    {
        //        return null;
        //    }
        //}

       

        //public ProductVariant GetProductVariantBySku(string sku)
        //{
        //    throw new System.NotImplementedException();
        //}

        //public int InsertProductVariantInfo(int productId, string name, string sku, decimal price, int displayOrder, int stockQuantity, int pictureId,
        //                                    bool published)
        //{
        //    var pv = new ProductVariant()
        //        {
        //            Name = name,
        //            Sku = sku,
        //            Price = price,
        //            DisplayOrder = displayOrder,
        //            StockQuantity = stockQuantity,
        //            PictureId = pictureId,
        //            Published = published,
        //            CreatedOnUtc = DateTime.Now,
        //            UpdatedOnUtc = DateTime.Now,
        //            ProductId = productId,
        //        };

        //    _productVariantRepository.Insert(pv);
        //    return pv.Id;

        //}

        //public void UpdateProductVariantInfo(int productVariantId, string name, string sku, decimal price, int displayOrder,
        //                                     int stockQuantity, int pictureId, bool published)
        //{
        //    var pv = _productVariantRepository.GetById(productVariantId);
        //    pv.Name = name;
        //    pv.Sku = sku;
        //    pv.Price = price;
        //    pv.DisplayOrder = displayOrder;
        //    pv.StockQuantity = stockQuantity;
        //    pv.PictureId = pictureId;
        //    pv.Published = published;
        //    _productVariantRepository.Update(pv);
        //}

        //public void InsertProductVariant(ProductVariant productVariant)
        //{
        //    throw new System.NotImplementedException();
        //}

        //public void UpdateProductVariant(ProductVariant productVariant)
        //{
        //    if (productVariant == null)
        //        throw new ArgumentNullException("productVariant");

        //    _productVariantRepository.Update(productVariant);
        //}

        //public IList<ProductVariant> GetProductVariantsByProductId(int productId)
        //{
        //    throw new System.NotImplementedException();
        //}

        //public void DeleteProductVariant(ProductVariant productVariant)
        //{
        //    throw new System.NotImplementedException();
        //}

        //public void AdjustInventory(ProductVariant productVariant, bool decrease, int quantity, string attributesXml)
        //{
        //    if (productVariant == null)
        //        throw new ArgumentNullException("productVariant");


        //    int newStockQuantity = 0;
        //    if (decrease)
        //        newStockQuantity = productVariant.StockQuantity - quantity;
        //    else
        //        newStockQuantity = productVariant.StockQuantity + quantity;


        //    productVariant.StockQuantity = newStockQuantity;
           

        //    UpdateProductVariant(productVariant);
        //}

        //public IList<ProductAttribute> GetAllProductAttributes()
        //{
        //    return _productAttributeRepository.Table.ToList();
        //}

        //public int InsertProductVariantAttribute(int pvId, AttributeControlType selectedAttributeType, int selectedProductAttributeId)
        //{
        //    var p = new ProductVariantAttribute()
        //    {
        //        ProductVariantId = pvId,
        //        AttributeControlType = selectedAttributeType,
        //        ProductAttributeId =  selectedProductAttributeId,
        //    };
        //    _productVariantAttributeRepository.Insert(p);
        //    return p.Id;
        //}

        //public IList<SpecificationAttribute> GetAllSpecificationAttribute()
        //{
        //    var query = _spRepository.Table;

        //    var p = query.ToList();
        //    if ( p!= null)
        //    {

        //        return p.Select(c=> new SpecificationAttribute()
        //        {
        //            Id = c.Id,

        //            Name = c.Name,
        //            DisplayOrder = c.DisplayOrder,

        //            SpecificationAttributeOptions = c.SpecificationAttributeOptions.Select(t=>new SpecificationAttributeOption()
        //                {
        //                    Id = t.Id,
        //                    Name = t.Name
        //                }).ToList()
        //        }).ToList();
        //    }
        //    else
        //    {
        //        return null;
        //    }
        //}

        //public void InsertProductSpecificationAttribute(int productId, int specificationAttributeOptionId)
        //{
        //    var p = _productRepository.GetById(productId);
        //    var spo = _spOptionRepository.GetById(specificationAttributeOptionId);
        //    var ps = new ProductSpecificationAttribute()
        //        {
        //            Product = p,
        //            SpecificationAttributeOption = spo,
        //        };

        //    p.ProductSpecificationAttributes.Clear();
        //    p.ProductSpecificationAttributes.Add(ps);
        //    _productRepository.Update(p);
        //}

        //public int InsertProductPicture(int productId, int pictureId, int displayOrder)
        //{

        //    var p = new ProductPicture()
        //        {
        //            DisplayOrder = displayOrder,
        //            PictureId = pictureId,
        //            ProductId = productId
        //        };
        //    _productPictureRepository.Insert(p);

        //    return p.Id;
        //    //var p = _productRepository.GetById(productId);
        //    //p.ProductPictures.Add(new ProductPicture()
        //    //    {
        //    //        PictureId = pictureId,
        //    //        ProductId = productId,
        //    //        DisplayOrder = displayOrder,

        //    //    });
        //    //_productRepository.Update(p);


        //}

        //public IList<ProductVariantAttribute> GetProductVariantAttributesByProductVariantId(int productVariantId)
        //{
        //    var pv = this.GetProductVariantById(productVariantId);
        //    if (pv != null)
        //    {
        //        return pv.ProductVariantAttributes.ToList();
        //    }

        //    else
        //    {
        //        throw  new Exception(string.Format("product variant id: {0} not exist", productVariantId));
        //    }

        //}

        //public ProductVariantAttribute GetProductVariantAttributeByProductVariantAttributeId(int productVariantAttributeId)
        //{
        //    var pva =  _productVariantAttributeRepository.GetById(productVariantAttributeId);

        //    if (pva != null)
        //    {
        //        return new ProductVariantAttribute()
        //            {
        //                ProductVariantId = pva.ProductVariantId,
        //                ProductAttribute = new ProductAttribute()
        //                    {
        //                        Name = pva.ProductAttribute.Name
        //                    },

        //                ProductVariantAttributeValues =
        //                    pva.ProductVariantAttributeValues == null
        //                        ? new List<ProductVariantAttributeValue>()
        //                        : pva.ProductVariantAttributeValues.Select(t => new ProductVariantAttributeValue()
        //                            {
        //                                Name = t.Name,
        //                                DisplayOrder = t.DisplayOrder
        //                            }).OrderBy(c=>c.DisplayOrder).ToList()
        //            };
        //    }
        //    return null;
        //}

        //public int InsertProductVariantAttributeValue(int productVariantAttributeId, string productVariantAttributeValue, int displayOrder)
        //{
        //    var pvav = new ProductVariantAttributeValue()
        //        {
        //            DisplayOrder = displayOrder,
        //            Name = productVariantAttributeValue,
        //            ProductVariantAttributeId = productVariantAttributeId
        //        };
        //    _productVariantAttributeValueRepository.Insert(pvav);
        //    return pvav.Id;
        //}

        //public ProductVariantAttributeValue GetProductVariantAttributeValueByProductVariantAttributeValueId(
        //    int productVariantAttributeValueId)
        //{

        //    var query = from pv in _productVariantAttributeValueRepository.Table
        //                where pv.Id == productVariantAttributeValueId
        //                select pv;

        //    var p = query.SingleOrDefault();
        //    if (p != null)
        //    {
        //        return new ProductVariantAttributeValue()
        //            {
        //                Id = p.Id,
        //                Name = p.Name,
        //                ProductVariantAttribute = new ProductVariantAttribute()
        //                    {
        //                        ProductAttribute = new ProductAttribute()
        //                            {
        //                                Name = p.ProductVariantAttribute.ProductAttribute.Name
        //                            }
        //                    }

        //            };
        //    }

        //    return null;

        //}

        //public void DeleteProductVaraintAttribute(int productvariantattributeId)
        //{
        //    var query = from pv in _productVariantAttributeRepository.Table
        //                where pv.Id == productvariantattributeId
        //                select pv;

        //    var p = query.SingleOrDefault();
        //    if (p != null)
        //    {
        //        _productVariantAttributeRepository.Delete(p);
        //    }
        //}

        //public void DeleteProductVaraint(int productVariantId)
        //{
        //    var query = from p in _productVariantRepository.Table
        //                where p.Id == productVariantId
        //                select p;

        //    var pv = query.SingleOrDefault();
        //    if (pv != null)
        //    {

        //        var product = pv.Product;
        //        if (product != null)
        //        {
        //            if (product.ProductVariants.Count > 1)
        //            {
        //                pv.Deleted = true;
        //                _productVariantRepository.Update(pv);
        //            }
        //            else
        //            {
        //                throw  new Exception("could not delete last product variant");
        //            }
        //        }
        //    }

        //}

        //public void DeleteProductVaraintAttributeValue(int productvariantattributeValueId)
        //{
        //    var query = from pva in _productVariantAttributeValueRepository.Table
        //                where pva.Id == productvariantattributeValueId
        //                select pva;

        //    var result = query.SingleOrDefault();
        //    if (result != null)
        //    {
        //        _productVariantAttributeValueRepository.Delete(result);
        //    }
        //}

        //public void DeleteProductPicture(int productPictureId)
        //{
        //    var query = from pp in _productPictureRepository.Table
        //                where pp.Id == productPictureId
        //                select pp;
        //    var pobject = query.SingleOrDefault();
        //    if (pobject != null)
        //    {
        //        _productPictureRepository.Delete(pobject);
        //    }
        //}

        public int CreateProductAttributeKey(int productId, string keyName)
        {
            //var productAttributeKeys = _productRep.GetById(productId).ProductAttributeKeys;
            //var pab = new ProductAttributeKey()
            //{
            //    ProductId = productId,
            //    Deleted = false,
            //    DisplayOrder = productAttributeKeys == null ? 1 : productAttributeKeys.Count + 1,
            //    Name = keyName,

            //};
            //_productAttributeKeyRep.Insert(pab);
            //return pab.Id;
            return 0;
        }

        public void InsertItems(int productId, IList<ItemGroup> itemCatalogGroups)
        {

            foreach (var itemCatalogGroup in itemCatalogGroups)
            {

                _itemGroupRep.Insert(itemCatalogGroup);
            }

               



            
            //;
            //return item.Id;
        }

        public int CreateProductAttributeValue(int itemId, string value, int productAttributeKeyId)
        {
            return 0;
            //var pav = new ProductAttributeValue()
            //{
            //    ItemId = itemId,
            //    Value = value,
            //    ProductAttributeKeyId = productAttributeKeyId,
            //};

            //_productAttributeValueRep.Insert(pav);
            //return pav.Id;
        }

        public IList<ProductAttributeKey> GetProductAttributeKeysByCatgory(int categoryId)
        {
            return _productAttributeKeyRep.Table.Where(c => c.CategoryId == categoryId && !c.IsEmpty).ToList();
        }

        public IList<ItemAttributeKey> GetItemAttributeKeysByCategory(int categoryId)
        {
            return _itemAttributeKeyRep.Table.Where(c => c.CategoryId == categoryId && !c.IsEmpty).ToList();
        }

        public Item GetItemById(int itemId)
        {
            var query = from t in _itemRep.Table
                where t.Id == itemId
                select t;
            return query.SingleOrDefault();
        }

        public void AdjustInventory(int itemId, bool decrease, int quantity)
        {
            var item = this.GetItemById(itemId);
            if (item == null)
                throw new ArgumentNullException("itemId");


            int newStockQuantity = 0;
            if (decrease)
                newStockQuantity = item.StockQuantity - quantity;
            else
                newStockQuantity = item.StockQuantity + quantity;


            item.StockQuantity = newStockQuantity;


            _itemRep.Update(item);
        }
      

        private string GenerateGroupCode()
        {
            return string.Empty;

        }

        public Product GetProduct(int productId)
        {
            return _productRep.GetById(productId);
        }

        public int InsertProduct(int shopId,
            string productName,
            string shortDescription,
            string fullDescription,
            decimal price,
            int stockQuantity,
            bool useProductAttribute,
            bool useItemAttribute,
            int productAttributeKeyId,
            int itemAttributeKeyId,
            int brandId,
            int categoryId,
            int pictureId,
            IList<string> productAttributeValues,
            IList<string> itemAttributeValues)
        {
            var p = new Product();
            p.ShopId = shopId;
            p.ProductName = productName;
            p.ShortDescription = shortDescription;
            p.FullDescription = fullDescription;
            p.Deleted = false;
            p.CreatedOn = DateTime.Now;
            p.UpdatedOn = DateTime.Now;

            p.CategoryId = categoryId;
            p.BrandId = brandId;
            p.Published = true;
            productAttributeKeyId = useProductAttribute ? productAttributeKeyId : GetEmptyProductAttribute();
            itemAttributeKeyId = useItemAttribute && useProductAttribute? itemAttributeKeyId : GetEmptyItemAttribute();
            p.UseProductAttribute = useProductAttribute;
            p.UseItemAttribute = useItemAttribute && useProductAttribute;
            p.ProductAttributeKeyId = productAttributeKeyId;
            p.ItemAttributeKeyId = itemAttributeKeyId;

            _productRep.Insert(p);

            if (productAttributeValues != null && productAttributeValues.Count > 0)
            {
                foreach (var pav in productAttributeValues)
                {
                    var productAttributeValue = new ProductAttributeValue()
                    {
                        ProductAttributeKeyId = productAttributeKeyId,
                        ProductId = p.Id,
                        Value = pav,
                    };

                    _productAttributeValueRep.Insert(productAttributeValue);
                }

            }
            else
            {
                var productAttributeValue = new ProductAttributeValue()
                {
                    ProductAttributeKeyId = productAttributeKeyId,
                    ProductId = p.Id,
                    Value = string.Empty,
                };

                _productAttributeValueRep.Insert(productAttributeValue);
            }

            if (itemAttributeValues != null && itemAttributeValues.Count > 0)
            {
                foreach (var iav in itemAttributeValues)
                {
                    var itemAttributeValue = new ItemAttributeValue()
                    {
                        ItemAttributeKeyId = itemAttributeKeyId,
                        ProductId = p.Id,
                        Value = iav,
                    };

                    _itemAttributeValueRep.Insert(itemAttributeValue);
                }
            }
            else
            {
                var itemAttributeValue = new ItemAttributeValue()
                {
                    ItemAttributeKeyId = itemAttributeKeyId,
                    ProductId = p.Id,
                    Value = string.Empty,
                };

                _itemAttributeValueRep.Insert(itemAttributeValue);
            }
           

            //if (useProductAttribute)
            //{
            //}
            //else
            //{
            //    var item = new Item()
            //    {
            //        ItemGroupCode = string.Format("{0}", p.Id),
            //        CreatedOn = DateTime.Now,
            //        UpdatedOn = DateTime.Now,
            //        Deleted = false,

            //        Price = price,
            //        StockQuantity = stockQuantity,
            //        ProductId = p.Id,
            //    };
            //    _itemRep.Insert(item);
            //}

           
            return p.Id;
        }

        private int GetEmptyItemAttribute()
        {
            return _itemAttributeKeyRep.Table.FirstOrDefault(c => c.IsEmpty).Id;
        }

        private int GetEmptyProductAttribute()
        {
            return _productAttributeKeyRep.Table.FirstOrDefault(c => c.IsEmpty).Id;
        }
    }
}